#pragma once

#include <functional>
#include <iostream>
#include <pthread.h>
#include <string>
namespace ThreadModule {
// 原⼦计数器，⽅便形成线程名称
std::uint32_t cnt = 0;

// 线程要执⾏的外部⽅法，我们不考虑传参，后续有std::bind来进⾏类间耦合

using threadfunc_t = std::function<void()>;
// 线程状态
enum class TSTATUS { THREAD_NEW, THREAD_RUNNING, THREAD_STOP };
// 线程
class Thread {
private:
  static void *run(void *obj) {
    Thread *self = static_cast<Thread *>(obj);
    pthread_setname_np(pthread_self(), self->_name.c_str()); // 设置线程名称
    self->_status = TSTATUS::THREAD_RUNNING;
    if (!self->_joined) {
      pthread_detach(pthread_self());
    }
    self->_func();
    return nullptr;
  }
  void SetName() {
    // 后期加锁保护
    _name = "Thread-" + std::to_string(cnt++);
  }

public:
  Thread(threadfunc_t func)
      : _status(TSTATUS::THREAD_NEW), _joined(true), _func(func) {
    SetName();
  }
  void EnableDetach() {
    if (_status == TSTATUS::THREAD_NEW)
      _joined = false;
  }
  void EnableJoined() {
    if (_status == TSTATUS::THREAD_NEW)

      _joined = true;
  }
  bool Start() {
    if (_status == TSTATUS::THREAD_RUNNING)
      return true;
    int n = ::pthread_create(&_id, nullptr, run, this);
    if (n != 0)
      return false;
    return true;
  }
  bool Join() {
    if (_joined) {
      int n = pthread_join(_id, nullptr);
      if (n != 0)
        return false;
      return true;
    }
    return false;
  }
  ~Thread() {}

private:
  std::string _name;
  pthread_t _id;
  TSTATUS _status;
  bool _joined;
  threadfunc_t _func;
};
} // namespace ThreadModule